package ch.csp.transformer;

import java.util.ArrayList;

import ch.csp.exchange.ParagraphWithLines;

public class ColumnedLineTransformer {

	private static final int SPACES = 10;
	private ArrayList<ParagraphWithLines> paragraphs;
	private final int columns;
	private int lengthOfALine;

	public ColumnedLineTransformer(
			ArrayList<ParagraphWithLines> paragraphsWithJustifiedLines,
			int columns) {
		this.paragraphs = paragraphsWithJustifiedLines;
		this.columns = columns;
	}

	public ArrayList<String> transform() {
		fillWhitespaces();
		validateAllLinesSameLength();
		ArrayList<String> flatLines = getFlatLines();
		//printOutLines(flatLines);
		ArrayList<String> columnedLines = createColumnedLines(flatLines);
		printOutLines(columnedLines);

		return columnedLines;
	}

	private void fillWhitespaces() {
		int longestLine = determineLongestLine();
		for (int i = 0; i < paragraphs.size(); i++) {
			for (int j = 0; j < paragraphs.get(i).lines.size(); j++) {
				String aLine = paragraphs.get(i).lines.get(j);
				aLine += createSpaces(longestLine - aLine.length());
				paragraphs.get(i).lines.set(j, aLine);
//				System.out.println("'" + aLine + "'");
//				System.out.println("'" + paragraphs.get(i).lines.get(j) + "'");
			}
		}
	}

	private int determineLongestLine() {
		int longestLine = 0;
		for (ParagraphWithLines paragraphWithLines : paragraphs) {
			for (String aLine : paragraphWithLines.lines) {
				if (aLine.length() > longestLine) {
					longestLine = aLine.length();
				}
			}
		}
		return longestLine;
	}

	private void validateAllLinesSameLength() {
		if(paragraphs.size() < 1) return;
		if(paragraphs.get(0).lines.size() < 1) return;
		lengthOfALine = paragraphs.get(0).lines.get(0).length();
		for (ParagraphWithLines paragraphWithLines : paragraphs) {
			for (String aLine : paragraphWithLines.lines) {
				if (aLine.length() != lengthOfALine) {
					throw new RuntimeException(
							"not all line lengths are equal. Current line: "
									+ aLine);
				}
			}
		}
	}

	private ArrayList<String> getFlatLines() {
		ArrayList<String> lines = new ArrayList<String>();
		for (ParagraphWithLines paragraphWithLines : paragraphs) {
			for (String aLine : paragraphWithLines.lines) {
				lines.add(aLine);
			}
			if (paragraphs.indexOf(paragraphWithLines) != paragraphs.size() - 1) {
				// add empty line at end of paragraph but not after last paragraph
				lines.add(createSpaces(lengthOfALine));
			}
		}
		return lines;
	}

	private void printOutLines(ArrayList<String> columnedLines) {
		System.out.println("print out lines: ");
		int line = 0;
		for (String aLine : columnedLines) {
			line++;
			System.out.println(String.format("%03d: %s", line, aLine));
		}
	}

	private ArrayList<String> createColumnedLines(ArrayList<String> flatLines) {
		ArrayList<String> columnedLines = new ArrayList<String>();
		int amountOfLines = flatLines.size();
		int minRequiredColumnLines = calcMinRequiredColumnLines(amountOfLines);
		int columnsInLastLine = calcColumnsInLastLine(amountOfLines);
		for (int currentColumnedLine = 0; currentColumnedLine < minRequiredColumnLines; currentColumnedLine++) {
			String aLine = "";
			int lineIndex = currentColumnedLine;
			for (int currentColumn = 0; currentColumn < columns; currentColumn++) {
				if (currentColumn == columnsInLastLine //
						&& currentColumnedLine + 1 == minRequiredColumnLines) {
					// last column in last line reached
					break;
				}
				aLine += flatLines.get(lineIndex) + createSpaces(SPACES);
				if (currentColumn < columnsInLastLine) {
					lineIndex += minRequiredColumnLines;
				} else {
					lineIndex += minRequiredColumnLines - 1;
				}
			}
			columnedLines.add(aLine);
		}
		return columnedLines;
	}
	
	private int calcMinRequiredColumnLines(int amountOfLines) {
		int amountOfLinesPerGraph = amountOfLines / columns;
		if (amountOfLines % columns != 0) {
			amountOfLinesPerGraph++;
		}
		return amountOfLinesPerGraph;
	}

	private int calcColumnsInLastLine(int amountOfLines) {
		int columnsInLastLine = amountOfLines % columns;
		if (columnsInLastLine == 0) {
			columnsInLastLine = columns;
		}
		return columnsInLastLine;
	}

	private String createSpaces(int amount) {
		String s = "";
		for (int i = 0; i < amount; i++) {
			s += " ";
		}
		return s;
	}

}
